package com.fishingwithme.controllers;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;

import com.fishingwithme.domain.user.UserService;
import com.fishingwithme.infrastructure.dtos.CodeVerifyDto;
import com.fishingwithme.infrastructure.dtos.DTO;
import com.fishingwithme.infrastructure.dtos.UserInfoDto;
import com.fishingwithme.infrastructure.dtos.UserPageDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/user")
@Tag(name = "User Management", description = "APIs for user profile management and administration")
public class UserController {

    @Autowired
    private UserService userService;


    /**
     * 分页查询用户列表
     *
     * @param pageNum  页码，默认1
     * @param pageSize 每页数量，默认10
     * @return 分页用户数据
     */
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/page")
    @Operation(
            summary = "Get users page (Admin only)",
            description = "Retrieve paginated list of users - requires admin role",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User page retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    public DTO<IPage<UserPageDto>> getUserPage(
            @Parameter(description = "Page number", example = "1")
            @RequestParam(defaultValue = "1") int pageNum,
            @Parameter(description = "Page size", example = "10")
            @RequestParam(defaultValue = "10") int pageSize) {
        IPage<UserPageDto> page = userService.getUserPage(pageNum, pageSize);
        return DTO.success(page);
    }

    @RequestMapping(path = "/getUserInfo")
    @Operation(
            summary = "Get current user information",
            description = "Retrieve detailed information of the currently authenticated user",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User information retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = UserInfoDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody UserInfoDto getUserInfo() {
        return userService.loadUserByUserId();
    }

    @PostMapping(path = "/emailVerify", produces = "application/json")
    @Operation(
            summary = "Send email verification",
            description = "Send verification code to user's email address",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Verification email sent successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(type = "boolean")
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody Boolean emailVerify(
            @Parameter(description = "Email address", required = true)
            @RequestBody DTO<String> email) {
        return userService.sendingEmail(email.getData());
    }

    @PostMapping(path = "/saveUserEmail", produces = "application/json")
    @Operation(
            summary = "Save user email",
            description = "Save user email address after verification",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Email saved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = CodeVerifyDto.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody CodeVerifyDto saveUserEmail(
            @Parameter(description = "Email verification information", required = true)
            @RequestBody CodeVerifyDto email) {
        return userService.saveUserEmail(email);
    }

    @PostMapping(path = "/saveUserNickName", produces = "application/json")
    @Operation(
            summary = "Update user nickname",
            description = "Update the nickname of the current user",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Nickname updated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(type = "string")
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody String saveUserNickName(
            @Parameter(description = "User nickname information", required = true)
            @RequestBody UserInfoDto nicknameDto) {
        return userService.saveUserNickName(nicknameDto.getNickname());
    }

    @PostMapping(path = "/saveUserAvatar", produces = "application/json")
    @Operation(
            summary = "Update user avatar",
            description = "Update the avatar URL of the current user",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Avatar updated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(type = "string")
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody String saveUserAvatar(
            @Parameter(description = "User avatar information", required = true)
            @RequestBody UserInfoDto avatar) {
        return userService.saveUserAvatar(avatar.getAvatarUrl());
    }

    @PostMapping(path = "/saveUserGender", produces = "application/json")
    @Operation(
            summary = "Update user gender",
            description = "Update the gender of the current user",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Gender updated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(type = "integer")
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody Integer saveUserGender(
            @Parameter(description = "User gender information", required = true)
            @RequestBody UserInfoDto gender) {
        return userService.saveUserGender(gender.getGender());
    }

    @RequestMapping(path = "/logout", produces = "application/json")
    @Operation(
            summary = "User logout",
            description = "Log out the current user",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User logged out successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(type = "boolean")
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            )
    })
    public @ResponseBody Boolean logout() {
        return userService.logout();
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping(path = "/enable", produces = "application/json")
    @Operation(
            summary = "Enable/disable user (Admin)",
            description = "Enable or disable a user account - requires admin role",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User status updated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    public @ResponseBody DTO<Boolean> cancel(
            @Parameter(description = "Enable status", required = true, example = "true")
            @RequestParam Boolean status,
            @Parameter(description = "User ID", required = true, example = "123")
            @RequestParam Long id) {
        return DTO.success(userService.cancel(status,id));
    }

    /**
     * 根据用户名搜索用户，限制返回10条结果
     *
     * @param username 用户名关键字
     * @return 用户列表
     */
    @GetMapping("/search")
    @Operation(
            summary = "Search users by username",
            description = "Search users by username keyword, limited to 10 results"
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Users found successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            )
    })
    public DTO<List<UserPageDto>> searchUsersByName(
            @Parameter(description = "Username keyword", required = true, example = "fisher")
            @RequestParam String username) {
        List<UserPageDto> users = userService.searchUsersByName(username);
        return DTO.success(users);
    }

    /**
     * 切换用户管理员权限（管理员操作）
     *
     * @param userId 用户ID
     * @param isAdmin 是否设为管理员（true/false）
     * @return 操作结果
     */

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/switch")
    @Operation(
            summary = "Switch user admin role (Admin)",
            description = "Grant or revoke admin privileges for a user - requires admin role",
            security = @SecurityRequirement(name = "Bearer Authentication")
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User admin status updated successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "401",
                    description = "Unauthorized - JWT token required"
            ),
            @ApiResponse(
                    responseCode = "403",
                    description = "Forbidden - Admin role required"
            )
    })
    public DTO<Boolean> switchAdmin(
            @Parameter(description = "User ID", required = true, example = "123")
            @RequestParam Long userId, 
            @Parameter(description = "Admin status", required = true, example = "true")
            @RequestParam Boolean isAdmin) {
        Boolean result = userService.switchAdmin(userId, isAdmin);
        return DTO.success(result);
    }
}
